#include "COFFFile.h"
#include <iostream>

COFFFile::COFFFile()
	: pHeader_(NULL)
{
}

BOOL COFFFile::Init(PBYTE  pBase, DWORD dwSize)
{
	if (FALSE == CFileBase::Init(pBase, dwSize))
	{
		return FALSE;
	}

	pHeader_ = (PIMAGE_FILE_HEADER)pBase_;

	PBYTE pOffset = pBase_ + sizeof(IMAGE_FILE_HEADER) + pHeader_->SizeOfOptionalHeader;
	for (int i = 0; i < pHeader_->NumberOfSections; ++i)
	{
		PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)pOffset; pOffset += sizeof(IMAGE_SECTION_HEADER);
		vctSectionHeaders_.push_back(pSec);
	}
	return TRUE;
}

BOOL COFFFile::UnInit()
{
	pHeader_ = NULL;
	return TRUE;
}

void COFFFile::PrintFileInfo(const char* szPrefix/* = ""*/)
{
	std::cout << szPrefix << "COFF File Type" << std::endl;
	switch (pHeader_->Machine)
	{
	case IMAGE_FILE_MACHINE_I386:
		std::cout << szPrefix << "Machine:I386;" << std::endl;
		break;
	case IMAGE_FILE_MACHINE_IA64:
		std::cout << szPrefix << "Machine:IA64;" << std::endl;
		break;
	case IMAGE_FILE_MACHINE_AMD64:
		std::cout << szPrefix << "Machine:AMD64;" << std::endl;
		break;
	default:
		break;
	}

	std::cout << szPrefix << "SizeOfOptionalHeader:" << pHeader_->SizeOfOptionalHeader << std::endl;
	std::cout << szPrefix << "TimeDateStamp:" << pHeader_->TimeDateStamp << std::endl;
	std::cout << szPrefix << "NumberOfSections:" << pHeader_->NumberOfSections << std::endl;
	std::cout << szPrefix << "NumberOfSymbols:" << pHeader_->NumberOfSymbols << std::endl;
	std::cout << szPrefix << "PointerToSymbolTable:" << pHeader_->PointerToSymbolTable << std::endl;
	for (auto& pSec : vctSectionHeaders_)
	{
		std::cout << szPrefix << "\t" << pSec->Name << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->VirtualAddress << " virtual address" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->SizeOfRawData << " size of raw data" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->PointerToRawData << " file pointer to raw data" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->PointerToRelocations << " file pointer to relocations" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->PointerToLinenumbers << " file pointer to line numbers" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->NumberOfRelocations << " number of relocations" << std::endl;
		std::cout << szPrefix << "\t\t" << pSec->NumberOfLinenumbers << " number of line numbers" << std::endl;
	}

	if (pHeader_->PointerToSymbolTable > 0)
	{
		PrintRawData(pBase_ + pHeader_->PointerToSymbolTable, sizeof(IMAGE_SYMBOL) * pHeader_->NumberOfSymbols, "\t\t");
	}
}
